﻿using Microsoft.AspNetCore.Authorization;
using MyWeb.Business.Base;
using MyWeb.Common.Helper;
using MyWeb.Model;
using MyWeb.Model.Models;
using MyWeb.Model.User;
using MyWeb.Repository.Base;
using MyWeb.Repository.UnitOfWorks;
using MyWeb.Services;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyWeb.Business.System.Impl
{
    public class UserService:BaseBusiness<SysUserInfo>, IUserService
    {
        readonly ISysUserInfoServices _sysUserInfoServices;
        readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly SqlSugarScope _dbBase;
        private readonly IBaseRepository<SysUserInfo> _baseUserRepository;
        readonly SysUserInfo _userinfo;

        public UserService(ISysUserInfoServices sysUserInfoServices, IUnitOfWorkManage unitOfWorkManage, SysUserInfo sysUser, IBaseRepository<SysUserInfo> baseUserRepository)
        {
            _sysUserInfoServices = sysUserInfoServices;
            _unitOfWorkManage = unitOfWorkManage;
            _dbBase = unitOfWorkManage.GetDbClient();
            _userinfo = sysUser;
            _baseUserRepository = baseUserRepository;
        }

        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<PageModel<SysUserInfo>> Get(int page = 1,int pageSize = 50, string key = "")
        {
            var data = await _baseUserRepository.QueryPage(a => a.IsDeleted != true && a.Status >= 0 && (a.LoginName != null && a.LoginName.Contains(key) || a.RealName != null && a.RealName.Contains(key)), page, pageSize, " Id desc ");


            var allUserRoles = await _dbBase.Queryable<UserRole>().Where(d => d.IsDeleted == false).ToListAsync();
            var allRoles = await _dbBase.Queryable<Role>().Where(d => d.IsDeleted == false).ToListAsync();
            //获取所有部门信息
            var allDepartments = await _dbBase.Queryable<Department>().Where(d => d.IsDeleted == false).ToListAsync();

            var sysUserInfos = data.data;
            foreach (var item in sysUserInfos)
            {
                var currentUserRoles = allUserRoles.Where(d => d.UserId == item.Id).Select(d => d.RoleId).ToList();
                item.RIDs = currentUserRoles;
                item.RoleNames = allRoles.Where(d => currentUserRoles.Contains(d.Id)).Select(d => d.Name).ToList();
                var departmentNameAndIds = GetFullDepartmentName(allDepartments, item.DepartmentId);
                item.DepartmentName = departmentNameAndIds.Item1;
                item.Dids = departmentNameAndIds.Item2;
            }

            return data;
        }

        /// <summary>
        /// 获取单个用户信息
        /// </summary>
        /// <param name="UserId">用户id</param>
        /// <returns></returns>
        public async Task<SysUserInfo> GetUserInfo(long UserId)
        {
            return await _dbBase.Queryable<SysUserInfo>().Where(t => t.Id == UserId).FirstAsync();
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="sysUserInfo">用户信息</param>
        /// <returns></returns>
        public async Task<bool> PutUserInfo(SysUserInfo sysUserInfo)
        {
            SysUserInfo _sysUserInfo = new SysUserInfo()
            {
                Id = sysUserInfo.Id,
                RealName = sysUserInfo.RealName,
                LoginName = sysUserInfo.LoginName,
                UpdateTime = DateTime.Now,
                DepartmentId = sysUserInfo.DepartmentId,
                Birth = sysUserInfo.Birth,
                Name = sysUserInfo.Name,
                Address = sysUserInfo.Address,
                RIDs = sysUserInfo.RIDs
            };

            _unitOfWorkManage.BeginTran();

            //无论新增还是修改，先清除用户角色关系表
            var com = await _dbBase.Deleteable<UserRole>().Where(u => u.UserId == _sysUserInfo.Id).ExecuteCommandAsync();
            //保存用户角色
            if (_sysUserInfo.RIDs.Count > 0)
            {
                var userRoles = new List<UserRole>();
                _sysUserInfo.RIDs.ForEach(rid => { userRoles.Add(new UserRole(_sysUserInfo.Id, rid)); });

                await _dbBase.Insertable(userRoles).ExecuteReturnSnowflakeIdListAsync();
            }

            var userinfo = _dbBase.Updateable(_sysUserInfo)
                .UpdateColumns(s => new { s.RealName, s.LoginName, s.UpdateTime, s.DepartmentId, s.Birth, s.Name, s.Address })
                .ExecuteCommand();

            _unitOfWorkManage.CommitTran();

            return true;
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="sysUserInfo"></param>
        /// <returns></returns>
        public async Task<bool> PostUserInfo(SysUserInfo sysUserInfo)
        {
            sysUserInfo.LoginPWD = MD5Helper.MD5Encrypt32(sysUserInfo.LoginPWD.IsNullOrEmpty() ? sysUserInfo.LoginName : sysUserInfo.LoginPWD);

            _unitOfWorkManage.BeginTran();
            //保存用户角色
            if (sysUserInfo.RIDs.Count > 0)
            {
                var userRoles = new List<UserRole>();
                sysUserInfo.RIDs.ForEach(rid => { userRoles.Add(new UserRole(sysUserInfo.Id, rid)); });

                await _dbBase.Insertable(userRoles).ExecuteReturnSnowflakeIdListAsync();
            }
            //插入数据，返回雪花Id
            var userId = await _dbBase.Insertable(sysUserInfo).ExecuteReturnSnowflakeIdAsync();

            _unitOfWorkManage.CommitTran();

            return true;
        }

        /// <summary>
        /// 删除用户信息
        /// </summary>
        /// <param name="uid">用户Id</param>
        /// <returns></returns>
        public async Task<object> DelUserInfo(long uid)
        {
            var userInfo = await _dbBase.Queryable<SysUserInfo>().Where(u => u.Id == uid && u.IsDeleted == false).FirstAsync();
            if (userInfo != null)
            {
                await _dbBase.Updateable<SysUserInfo>().SetColumns(u => u.IsDeleted == true).Where(u => u.Id == userInfo.Id).ExecuteCommandAsync();

                return "删除成功";
            }
            else
            {
                return "用户Id不存在！";
            }
        }

        /// <summary>
        /// 获取用户详情根据token
        /// 【无权限】
        /// </summary>
        /// <param name="token">令牌</param>
        /// <returns></returns>
        public async Task<SysUserInfo> GetInfoByToken(string token)
        {
            SysUserInfo data = new SysUserInfo();
            if (!string.IsNullOrEmpty(token))
            {
                var tokenModel = JwtHelper.SerializeJwt(token);
                if (tokenModel != null && tokenModel.Uid > 0)
                {
                    var userinfo = await _baseUserRepository.QueryById(tokenModel.Uid);
                    if (userinfo != null)
                    {
                        data = userinfo;
                    }
                }
            }

            return data;
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public async Task<string> RemovePwd(long UserId)
        {
            var user = await _dbBase.Queryable<SysUserInfo>().Where(u => u.Id == UserId).FirstAsync();
            if (user.Name.IsNullOrEmpty())
            {
                return "用户不存在！";
            }

            await _dbBase.BeginTranAsync();

            user.LoginPWD = MD5Helper.MD5Encrypt32(user.Name);
            user.Name = user.LoginName;

            await _dbBase.Updateable<SysUserInfo>(user)
                .Where(u => u.Id == user.Id)
                .UpdateColumns(u => new { u.LoginPWD })
                .EnableDiffLogEvent()
                .ExecuteCommandAsync();

            await _dbBase.CommitTranAsync();
            return "成功";
        }

        /// <summary>
        /// 获取部门
        /// </summary>
        /// <param name="departments"></param>
        /// <param name="departmentId"></param>
        /// <returns></returns>
        private (string, List<long>) GetFullDepartmentName(List<Department> departments, long departmentId)
        {
            var departmentModel = departments.FirstOrDefault(d => d.Id == departmentId);
            if (departmentModel == null)
            {
                return ("", new List<long>());
            }

            var pids = departmentModel.CodeRelationship?.TrimEnd(',').Split(',').Select(d => long.Parse(d)).ToList();
            pids.Add(departmentModel.Id);
            var pnams = departments.Where(d => pids.Contains(d.Id)).ToList().Select(d => d.Name).ToArray();
            var fullName = string.Join("/", pnams);

            return (fullName, pids);
        }
    }
}
